package com.xbongbong.paas.toolbox.util;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.PatternEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.pro.enums.errorcodes.BiErrorCodeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.Stack;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: wufeng
 * @date: 2018/10/19 9:49
 * @desrcption: 正则校验
 */
public class RegexUtil {

    /**
     * 数字校验规则
     */
    private static Pattern numPattern = Pattern.compile("^-?\\d+(\\.\\d+)?([eE]\\d+)?$");
    /**
     * 整数校验规则
     */
    private static Pattern INTEGER_PATTERN = Pattern.compile("^-?[1-9]\\d*$");

    private static Pattern twoPositiveInt = Pattern.compile("^([12][0-9]|30|[1-9])$");

    private static Pattern zipCodePattern = Pattern.compile(PatternEnum.POSTCODE.getPattern());

    private static Pattern emailPattern = Pattern.compile(PatternEnum.EMAIL.getPattern());

    private static Pattern phonePattern = Pattern.compile(PatternEnum.PHONE.getPattern());

    private static Pattern mobilePattern = Pattern.compile(PatternEnum.MOBILE.getPattern());

    private static Pattern onePositiveInt = Pattern.compile("^[0-9]$");

    private static final Pattern isDate = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");

    private static final Pattern isTime = Pattern.compile("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}");

    private static final Pattern isTimeNoSecond = Pattern.compile("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}");

    private final static Pattern pattern = Pattern.compile("\\{[self.\\|_widget_\\|_formula_\\|ext\\|\\d.\\|dept.\\|user.]([\\s\\S]*?)\\}");

    private static Pattern urlPattern = Pattern.compile(PatternEnum.URL.getPattern());

    private final static Pattern DECIMAL_POINT_PATTERN = Pattern.compile("\\.");

    /**
     * 判断首尾的双引号和单引号
     */
    private final static Pattern APOSTROPHE_DOUBLE_QUOTERS = Pattern.compile("(^\".*|.*\"$)|(^'.*|.*'$)");

    /**
     * 数字占位符
     */
    private final static Pattern DECIMAL_FORMAT = Pattern.compile("^.*#\\.#+$");

    /**
     * 数字占位符
     */
    private final static Pattern DECIMAL_PERCENT_SIGN_FORMAT = Pattern.compile("^.*#\\.#+%{1}$");

    private final static Pattern NUMERIC_PERCENT_SIGN_PLACEHOLDER = Pattern.compile("^.*0\\.0+%{1}$");
    /**
     * 数字占位补位符
     */
    private final static Pattern NUMERIC_PLACEHOLDER = Pattern.compile("^.*0\\.0+$");
    private final static Pattern ROW_DATA_FORMAT = Pattern.compile("^.*\\[Num0\\]$");

    /**
     * 公式运算符
     */
    private final static Pattern OPERATOR_PATTERN = Pattern.compile("\\-|\\+|\\*|\\%|\\/|\\^|(|)");

    private final static Pattern SQUARE_BRACKETS = Pattern.compile("(\\[{1}(.*?)\\]{1})");

    private final static Pattern TABLE_FIELD_I18N = Pattern.compile("\\$_\\{\\S+}");

    /**
     * 出现11个‘(’ 或者 ‘)’
     **/
    private static Pattern bracketsPattern = Pattern.compile(".*\\(.*\\(.*\\(.*\\(.*\\(.*\\(.*\\(.*\\(.*\\(.*\\(.*\\(.*|.*\\).*\\).*\\).*\\).*\\).*\\).*\\).*\\).*\\).*\\).*\\).*");
    /**
     * 左括号的数量
     **/
    private static Pattern leftBrackets = Pattern.compile("\\(");
    /**
     * 右括号的数量
     **/
    private static Pattern rightBrackets = Pattern.compile("\\)");
    /**
     * 提取最外层公式的大写英文
     **/
    private static Pattern formulaNamePattern = Pattern.compile("^[A-Z]+");
    /**
     * 提取最日期外层公式的大写英文
     **/
    private static Pattern formulaDateNamePattern = Pattern.compile("^[A-Z]+[_][A-Z]+");
    /**
     * 提取最外层公式的变量
     **/
    public static Pattern formulaFieldPattern = Pattern.compile("^[A-Z]+\\(|\\)$");
    /**
     * 提取日期最外层公式的变量
     **/
    private static Pattern formulaDateFieldPattern = Pattern.compile("^[A-Z]+[_][A-Z]+\\(|\\)$");
    /**
     * 分割公式的每一个变量
     **/
    public static Pattern formulaFieldsPattern = Pattern.compile("\\{num_[0-9]+\\}|[0-9]+\\.[0-9]+|-[0-9]+\\.[0-9]+|\\{[0-9]+.(num|long)_[0-9]+\\}|\\{[0-9]+.ownerId_[0-9]+\\}|\\{[0-9]+.creatorId\\}|\\{[0-9]+.serialNo\\}|\\{[0-9]+.text_[0-9]+\\}|\\{[0-9]+.ownerId\\}|[0-9]+|-[0-9]+|[A-Z]+\\(|,|\\>=|\\<=|\\!=|\\u003c|\\u003e|\\==|\\)");
    /**
     * 检测变量是否是一个公式
     **/
    public static Pattern checkFormulaField = Pattern.compile("^[A-Z]+\\(.*\\)$");
    /**
     * 检测变量是否是一个日期公式
     **/
    public static Pattern checkFormulaDateField = Pattern.compile("^[A-Z]+[_]+[A-Z]+\\(.*\\)$");
    /**
     * 检测逻辑符号
     **/
    public static Pattern checkLogicalSymbol = Pattern.compile("\\>=|\\<=|\\!=|\\u003c|\\u003e|\\==|\\=");
    /**
     * 检测是否有 "、小写字母、汉字
     **/
    private static Pattern formulaStandard = Pattern.compile("(.*[！~@#$%^&*\\\\+?~！@#￥%…&*—【】、？\'].*|.*[\\u4E00-\\u9FA5].*|.*(\\)[A-Z]+).*)");
    /**
     * 检测是否有 "、汉字
     **/
    private static Pattern workOrderV2FormulaStandard = Pattern.compile("(.*[！~@#$%^&*\\\\+?~！@#￥%…&*—【】、？\'].*|.*[\\u4E00-\\u9FA5])");
    /**
     * 日期相减
     */
    public static final String DATE_DIFF = "DATE_DIFF";
    /**
     * 负数
     */
    public static final Pattern checkNegative = Pattern.compile("-[0-9]*.?[0-9]");
    /**
     * 检测加减乘除符号结尾
     **/
    private static Pattern checkSpecialEndingSymbol = Pattern.compile("(\\+|\\?|-|\\*|/).*(\\))$");
    /**
     * 特殊符号
     **/
    private static Pattern specialSymbol = Pattern.compile("[+\\-&*?(){}\\[\\]]");
    /**
     * 加小括号数字校验规则
     */
    public static Pattern specialNumPattern = Pattern.compile("^(\\()*-?\\d+(\\.\\d+)?([eE]\\d+)?(\\))*");
    /**
     * 检测加减乘除符号
     **/
    private static Pattern operationSymbol = Pattern.compile(".*(\\+|\\?|-|\\*|/).*");
    /**
     * 根据正则表达式校验数据是否合适
     * @param value 值
     * @param regex 正则表达式
     * @return 如果value 符合 regex的正则表达式格式,返回true, 否则返回 false;
     */
    public static boolean matchByRegex(String value, String regex){
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(value);
        return matcher.matches();
    }

    /**
     * 判断一个字符串是否是数字。
     *
     * @param string
     * @return
     */
    public static boolean isNumber(String string) {
        if (string == null){
            return false;
        }
        Matcher matcher = numPattern.matcher(string);
        return matcher.matches();
    }

    /**
     * 判断一个字符串是否是整数。
     *
     * @param string
     * @return
     */
    public static boolean isInteger(String string) {
        if (string == null) {
            return false;
        }
        Matcher matcher = INTEGER_PATTERN.matcher(string);
        return matcher.matches();
    }

    /**
     * 判断一个字符串是否是邮政编码
     *
     * @param zipCode
     * @return
     */
    public static boolean isZipCode(String zipCode) {
        if (zipCode == null){
            return false;
        }
        Matcher matcher = zipCodePattern.matcher(zipCode);
        return matcher.matches();
    }

    /**
     * 判断一个字符串是否是数字。
     *
     * @param email
     * @return
     */
    public static boolean isEmail(String email) {
        if (email == null){
            return false;
        }
        Matcher matcher = emailPattern.matcher(email);
        return matcher.matches();
    }

    /**
     * 判断一个字符串是否是电话
     *
     * @param phone
     * @return
     */
    public static boolean isPhone(String phone) {
        if (phone == null){
            return false;
        }
        Matcher matcher = phonePattern.matcher(phone);
        return matcher.matches();
    }

    /**
     * 判断一个字符串是否是电话
     *
     * @param mobile
     * @return
     */
    public static boolean isMobile(String mobile) {
        if (mobile == null){
            return false;
        }
        Matcher matcher = mobilePattern.matcher(mobile);
        return matcher.matches();
    }
    /**
     * 判断是否为一个2到30的正整数
     * @param string
     * @return
     */
    public static boolean isTwoPositiveInt(String string){
        if (string == null){
            return false;
        }
        Matcher matcher = twoPositiveInt.matcher(string);
        return matcher.matches();
    }

    /**
     * 判断是否为一个2到30的正整数
     * @param string
     * @return
     */
    public static boolean isOnePositiveInt(String string){
        if (string == null){
            return false;
        }
        Matcher matcher = onePositiveInt.matcher(string);
        return matcher.matches();
    }

    public static Boolean isDateSDF(String value) {
        // 是yyyy-MM-dd
        Matcher matcher = isDate.matcher(value);
        return matcher.matches();
    }

    public static Boolean isDate(String value) {

        Matcher matcher = isDate.matcher(value);
        Matcher isTimeMatcher = isTime.matcher(value);
        Matcher isTimeNoSecondMatcher = isTimeNoSecond.matcher(value);
        // 是yyyy-MM-dd 或者 yyyy-MM-dd HH:mm 或者 yyyy-MM-dd HH:mm:SS
        return matcher.matches() || isTimeMatcher.matches() || isTimeNoSecondMatcher.matches();
    }

    public static Boolean isTime(String value) {
        // 是yyyy-MM-dd HH:mm:SS
        Matcher matcher = isTime.matcher(value);
        return matcher.matches();
    }
    public static Boolean isTimeNoSecond(String value) {
        // 是yyyy-MM-dd HH:mm
        Matcher matcher = isTimeNoSecond.matcher(value);
        return matcher.matches();
    }

    /**
     * 截取以{self.开头等，以}结尾的字符串，即获取公式级别的attr
     * @param value
     * @return ["{self.text_1}"]
     */
    public static String[] getFormulaAttr(String value) {
        String[] arr = new String[0];
        Matcher matcher = pattern.matcher(value);
        while (matcher.find()) {
            arr = Arrays.copyOf(arr,arr.length+1);
            arr[arr.length-1]=matcher.group();
        }
        return arr;
    }

    public static String[] splitByDecimalPoint(String value) {
        String[] arr = value.split("\\.");
        return arr;
    }
    /**
     * 判断字符串是不是以数字开头
     * @param str
     * @return
     */
    public static boolean isStartWithNumber(String str) {

        Integer startNum = str.indexOf(".");
        String value = str.substring(0, startNum).replaceAll("[\\{\\}]", "");
        return isInteger(value);
    }

    /**
     * 以单引号或者双引号为首尾的字符串
     * @param str
     * @return
     */
    public static boolean startQuotes(String str) {

        Matcher matcher = APOSTROPHE_DOUBLE_QUOTERS.matcher(str);
        return matcher.matches();
    }

    /**
     * 判断数字占位符
     * @param str
     * @return
     */
    public static boolean decimalFormat(String str) {
        Matcher matcher = DECIMAL_FORMAT.matcher(str);
        return matcher.matches();
    }

    /**
     * 判断数字占位符
     * @param str
     * @return
     */
    public static boolean decimalPercentSignFormat(String str) {
        Matcher matcher = DECIMAL_PERCENT_SIGN_FORMAT.matcher(str);
        Matcher matcher1 = NUMERIC_PERCENT_SIGN_PLACEHOLDER.matcher(str);

        return matcher.matches() || matcher1.matches();
    }

    /**
     * 判断数字占位补位符
     * @param str
     * @return
     */
    public static boolean numericPlaceholder(String str) {
        Matcher matcher = NUMERIC_PLACEHOLDER.matcher(str);
        return matcher.matches();
    }

    /**
     * 判断数字占位补位符
     * @param str
     * @return
     */
    public static boolean rowDataFormat(String str) {
        Matcher matcher = ROW_DATA_FORMAT.matcher(str);
        return matcher.matches();
    }

    public static boolean hasOperator(String value) {
        Matcher matcher = OPERATOR_PATTERN.matcher(value);
        return matcher.find();
    }

    public static boolean squareBrackets(String value) {
        Matcher matcher = SQUARE_BRACKETS.matcher(value);
        return matcher.matches();
    }

    public static String getVariableName(String value) {
        if (StringUtils.isEmpty(value)) {
            return value;
        }
        Matcher matcher = TABLE_FIELD_I18N.matcher(value);
        if (matcher.matches()) {
            String name = value.substring(3, value.length()-1);
            return I18nMessageUtil.getMessage(name);
        }
        return value;
    }

    /**
     * 判断公式的括号是不是超出了10个
     * @param formula 公式
     * @return boolean 返回true表示匹配成功，公式不符合规范
     */
    public static boolean checkBracketsNumber(String formula) {
        if (formula == null) {
            return true;
        }
        Matcher matcher = bracketsPattern.matcher(formula);
        return matcher.matches();
    }

    /**
     * @Description  检测公式不能有"、小写字母、汉字
     * @param  formula 公式
     * @return boolean  返回true 说明检测匹配成功，公式不符合规范
     * @author weiming
     * @Date  2020/11/4/9:35
     * @since
     **/
    public static boolean checkFormulaStandard(String formula) {
        if (formula == null) {
            return true;
        }
        Matcher matcher = formulaStandard.matcher(formula);
        return matcher.matches();
    }

    /**
     * 检测公式不能有"、汉字 (注：formulaStandard 会校验小写字母，所以另外写)
     * @param businessType
     * @param formula
     * @return
     */
    public static boolean checkWorkOrderV2FormulaStandard(Integer businessType, String formula) {
        if (Objects.equals(XbbRefTypeEnum.WORK_ORDER_V2_NODE_LOG_INFO.getCode(), businessType)
                && !Objects.isNull(formula)) {
            Matcher matcher = workOrderV2FormulaStandard.matcher(formula);
            return matcher.matches();
        }
        return false;
    }

    /**
     * 判断公式的括号是否匹配
     * @param formula 公式
     * @return 返回true时，说明检测匹配成功，公式不符合规范
     * @author weiming
     * @Date  2020/11/4/9:35
     */
    public static boolean checkBracketsMatch(String formula) {
        Map<Character, Character> map = new HashMap<>();
        map.put(')', '(');
        map.put(']', '[');
        map.put('}', '{');
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < formula.length(); i++) {
            Character c = formula.charAt(i);
            if (map.containsValue(c)) {
                stack.push(c);
            } else if (map.containsKey(c)) {
                if (stack.empty()) {
                    return false;
                }
                if (map.get(c).equals(stack.peek())) {
                    stack.pop();
                } else {
                    return false;
                }
            }
        }
        return stack.empty();
    }

    /**
     * 判断公式是否含有公式的大写英文
     * @param string
     * @return 返回true时，代表校验不通过
     */
    public static boolean checkFormulaSign(String string) {
        if (string == null) {
            return true;
        }
        return !checkFormulaField.matcher(string).matches() && !checkFormulaDateField.matcher(string).matches();
    }

    /**
     * @Description 提取公式的大写英文
     * @param textString 公式
     * @return java.lang.String
     * @author weiming
     * @Date  13:33
     * @since
     **/
    public static String extractFormulaName(String textString){
        String name =null;
        if (textString == null) {
            return null;
        }
        Matcher dateMatcher = formulaDateNamePattern.matcher(textString);
        if (dateMatcher.find()) {
            name = dateMatcher.group();
        }else {
            Matcher matcher = formulaNamePattern.matcher(textString);
            if (matcher.find()) {
                name = matcher.group();
            }
        }
        return name;
    }

    /**
     * @Description 公式转换的第一步处理
     * @param textString 页面保存的公式
     * @return java.lang.String
     * @author weiming
     * @Date  13:38
     * @since
     **/
    public static String formulaTranslate(String textString, List<String> fieldList, Map<String, Set<String>> divideMap) throws XbbException {
        //最终拼接的公式
        StringBuilder textFormulaString = new StringBuilder("(");
        //最外层公式的大写英文
        String formulaName = extractFormulaName(textString);
        //最外层公式的变量数组,将最外层的全部变量赋值给fields
        String fields = "";
        if (Objects.equals(formulaName,DATE_DIFF)){
            return "";
        }else {
            fields = formulaFieldPattern.split(textString)[1];
        }
        //建立栈，控制括号的匹配
        Stack stack = new Stack();
        Matcher matcher = formulaFieldsPattern.matcher(fields);
        //拼接（公式作为变量）
        StringBuilder sb = new StringBuilder();
        //变量集合
        List<String> fieldsList = new ArrayList<>();
        while (matcher.find()) {
            String group = matcher.group();
            if (group.startsWith("[") && group.contains("]")) {
                fieldsList.add(group);
            } else if (group.contains("(") && !group.contains(")")) {
                sb.append(group);
                stack.push(1);
            } else {
                //如果栈空
                if (stack.empty()) {
                    if (",".equals(group)){
                        continue;
                    }else if (RegexUtil.isNumber(group) && checkNegative.matcher(group).matches()){
                        fieldsList.add("(" + group + ")");
                    }else {
                        fieldsList.add(group);
                    }
                } else {//如果栈不为空
                    sb.append(group);
                    if (")".equals(group)) {
                        stack.pop();
                        if (stack.empty()) {
                            fieldsList.add(sb.toString());
                            sb.delete(0, sb.length());
                        }
                    }
                }
            }
        }
        if ("IF".equals(formulaName)) {
            if((fieldsList.size() != 5) || !checkLogicalSymbol.matcher(fieldsList.get(1)).matches()){
                throw new XbbException(BiErrorCodeEnum.API_ERROR_241017,BiErrorCodeEnum.API_ERROR_241017.getMsg());
            }
            String preString = "";
            String symbol = "";
            String sufString = "";
            for (int i = 0; i < fieldsList.size(); i++) {
                String s = fieldsList.get(i);
                switch (i) {
                    case 0:
                        List<String> tempList = new ArrayList<>();
                        preString = checkFormulaField.matcher(s).matches() ? formulaTranslate(s,tempList,divideMap) : s;
                        if (CollectionsUtil.isNotEmpty(tempList)){
                            fieldList.addAll(tempList);
                        }else {
                            if (!RegexUtil.isNumber(s)){
                                fieldList.add(s);
                            }
                        }
                        break;
                    case 1:
                        symbol = s;
                        break;
                    case 2:
                        List<String> tempList2 = new ArrayList<>();
                        sufString = checkFormulaField.matcher(s).matches() ? formulaTranslate(s,tempList2,divideMap) : s;
                        if (CollectionsUtil.isNotEmpty(tempList2)){
                            fieldList.addAll(tempList2);
                        }else {
                            if (!RegexUtil.isNumber(s)){
                                fieldList.add(s);
                            }
                        }
                        break;
                    case 3:
                        List<String> tempList3 = new ArrayList<>();
                        String sufString3 = checkFormulaField.matcher(s).matches() ? formulaTranslate(s,tempList3,divideMap) : s;
                        if (CollectionsUtil.isNotEmpty(tempList3)){
                            fieldList.addAll(tempList3);
                        }else {
                            if (!RegexUtil.isNumber(s)){
                                fieldList.add(s);
                            }
                        }
                        break;
                    case 4:
                        List<String> tempList4 = new ArrayList<>();
                        String sufString4 = checkFormulaField.matcher(s).matches() ? formulaTranslate(s,tempList4,divideMap) : s;
                        if (CollectionsUtil.isNotEmpty(tempList4)){
                            fieldList.addAll(tempList4);
                        }else {
                            if (!RegexUtil.isNumber(s)){
                                fieldList.add(s);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            List<String> tempList1 = new ArrayList<>();
            String field1 = fieldsList.get(fieldsList.size() - 2);
            if (!checkFormulaSign(field1)) {
                field1 = formulaTranslate(field1,tempList1,divideMap);
            }
            List<String> tempList2 = new ArrayList<>();
            String field2 = fieldsList.get(fieldsList.size() - 1);
            if (!checkFormulaSign(field2)) {
                field2 = formulaTranslate(field2,tempList2,divideMap);
            }
            textFormulaString.append(preString + symbol + sufString + "?" + field1 + ":" + field2).append(")");
        } else if ("SUMIF".equals(formulaName)) {
            if(fieldsList.size() < 3 || !checkLogicalSymbol.matcher(fieldsList.get(fieldsList.size()-2)).matches()){
                throw new XbbException(BiErrorCodeEnum.API_ERROR_241017, BiErrorCodeEnum.API_ERROR_241017.getMsg());
            }
            StringBuilder logicalSymbol = new StringBuilder();
            StringBuilder tempScript = new StringBuilder("(");
            List<String> paramsList = new ArrayList<>();
            for (int i = 0; i < fieldsList.size(); i++) {
                String s = fieldsList.get(i);
                if (checkFormulaField.matcher(s).matches()) {
                    s = formulaTranslate(s,new ArrayList<>(),divideMap);
                }
                if (checkLogicalSymbol.matcher(s).matches()) {
                    logicalSymbol.append(s);
                } else {
                    if (logicalSymbol.toString().length() == 0) {
                        paramsList.add(s);
                    }
                }
                if (i == fieldsList.size() - 1) {
                    logicalSymbol.append(s);
                }
            }
            for (int i = 0; i < paramsList.size(); i++) {
                String s = paramsList.get(i);
                //如果s是数字，
                if (!(s.contains("num") || s.contains("date"))){
                    throw new XbbException(BiErrorCodeEnum.API_ERROR_241017,BiErrorCodeEnum.API_ERROR_241017.getMsg());
                }
                if (i == (paramsList.size() - 1)) {
                    tempScript.append(s).append(logicalSymbol).append('?').append(s).append(":0");
                } else {
                    tempScript.append(s).append(logicalSymbol).append("?").append(s).append(":0").append("+");
                }
            }
            tempScript.append(')');
            textFormulaString = tempScript;
        } else {
            StringBuffer tempTextFormulaString = new StringBuffer(textFormulaString);
            for (int i = 0; i < fieldsList.size(); i++) {
                String s = fieldsList.get(i);
                //先判断变量是不是公式
                List<String> tempList = new ArrayList<>();
                if (checkFormulaField.matcher(s).matches() || checkFormulaDateField.matcher(s).matches()) {
                    s = formulaTranslate(s,tempList,divideMap);
                    if (CollectionsUtil.isNotEmpty(tempList)){
                        fieldList.addAll(tempList);
                    }
                }
                if (CollectionsUtil.isEmpty(tempList)){
                    if (!RegexUtil.isNumber(s)){
                        fieldList.add(s);
                    }
                }
                try {
                    //根据公式的大写英文与当前变量拼接公式
                    montageFormula(formulaName, textFormulaString, s);
                } catch (XbbException e) {
                    throw new XbbException(BiErrorCodeEnum.API_ERROR_241017,BiErrorCodeEnum.API_ERROR_241017.getMsg());
                }
                //如果是最后一个变量
                if (i == (fieldsList.size() - 1)) {
                    textFormulaString.delete(textFormulaString.length() - 1, textFormulaString.length());
                    textFormulaString.append(')');
                    if ("AVERAGE".equals(formulaName)) {
                        textFormulaString.insert(0, '(');
                        textFormulaString.append("/" + fieldsList.size());
                        textFormulaString.append(')');
                    }
                }
            }
            Boolean divFlag = Objects.equals(formulaName,"DIVIDE");
            Boolean maxOrMinFlag = Objects.equals(formulaName,"MAX") ||  Objects.equals(formulaName,"MIN");
            Map<String, Set<String>> tempDivideMap = new HashMap<>(divideMap);
            if (divFlag){
                for (String item : fieldsList) {
                    //先判断变量是不是公式
                    if (checkFormulaField.matcher(item).matches() || checkFormulaDateField.matcher(item).matches()) {
                        item = formulaTranslate(item,new ArrayList<>(),tempDivideMap);
                        if (Objects.equals(item,"0")){
                            return "0";
                        }
                    }
                    if (!specialNumPattern.matcher(item).matches()) {
                        if (divideMap.containsKey(item)) {
                            Set<String> set = divideMap.get(item);
                            set.add(textFormulaString.toString().replaceAll("[\\[\\]]", ""));
                            tempDivideMap.put(item, set);
                        } else {
                            Set<String> set = new HashSet<>();
                            set.add(textFormulaString.toString().replaceAll("[\\[\\]]", ""));
                            tempDivideMap.put(item, set);
                        }
                    }else {
                        item = item.replaceAll("\\(","").replaceAll("\\)","");
                        if (new BigDecimal("0").compareTo(new BigDecimal(item)) == 0){
                            tempDivideMap.clear();
                            return "0";
                        }
                    }
                }
            }else if (maxOrMinFlag){
                StringBuffer maxOrMinFormula = new StringBuffer();
                for (int i = 0; i < fieldsList.size(); i++) {
                    String s = fieldsList.get(i);
                    //先判断变量是不是公式
                    if (checkFormulaField.matcher(s).matches() || checkFormulaDateField.matcher(s).matches()) {
                        s = formulaTranslate(s,new ArrayList<>(),new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
                    }
                    if (i == 0 ){
                        maxOrMinFormula.append(s);
                    }else {
                        if (i >= 2){
                            maxOrMinFormula.insert(0,"(");
                            maxOrMinFormula.append(")");
                        }
                        String tempBs = maxOrMinFormula.toString();
                        maxOrMinFormula.append(">="+s+"?"+ tempBs+":"+s);
                    }
                }
                return tempTextFormulaString.append(maxOrMinFormula).append(')').toString().replaceAll("[\\[\\]]", "");
            }
            divideMap.clear();
            divideMap.putAll(tempDivideMap);
        }
        return textFormulaString.toString().replaceAll("[\\[\\]]", "");
    }

    /**
     * @Description 根据公式名拼装公式
     * @param formulaName, textFormulaString, s
     * @return void
     * @author weiming
     * @Date  2020/10/26/16:36
     * @since
     **/
    public static void montageFormula(String formulaName, StringBuilder textFormulaString, String param) throws XbbException {
        switch (formulaName) {
            case "ADD":
            case "AVERAGE":
            case "SUM":
                textFormulaString.append(param).append('+');
                break;
            case "SUBTRACT":
                textFormulaString.append(param).append('-');
                break;
            case "MULTIPLY":
                textFormulaString.append(param).append('*');
                break;
            case "DIVIDE":
                textFormulaString.append(param).append('/');
                break;
            case "DATE_DIFF":
            case "MAX":
            case "MIN":
                textFormulaString.append(param).append(',');
                break;
            default:
                throw new XbbException(BiErrorCodeEnum.API_ERROR_241017,BiErrorCodeEnum.API_ERROR_241017.getMsg());
        }
    }
    /**
     * 根据正则表达式校验数据是否合适
     * @param value 值
     * @return 如果value 符合 regex的正则表达式格式,返回true, 否则返回 false;
     */
    public static String filterLogicalOperationsSymbol(String value){
        Matcher matcher = checkSpecialEndingSymbol.matcher(value);
        if (matcher.find()){
            String word = matcher.group();
            value = value.replaceAll(transferSpecialSymbol(word),")");
        }
        return value;
    }

    /**
     * 根据正则表达式校验数据是否合适
     * @param value 值
     * @return 如果value 符合 regex的正则表达式格式,返回true, 否则返回 false;
     */
    public static String transferSpecialSymbol(String value){
        Matcher matcher = specialSymbol.matcher(value);
        Set<String> distinctSet = new HashSet<>();
        while (matcher.find()){
            String word = matcher.group();
            if (distinctSet.contains(word)){
                continue;
            }
            distinctSet.add(word);
            word = "\\" + word;
            value = value.replaceAll(word,"\\"+ word);

        }
        return value;
    }
    /**
     * 判断一个字符串是否包含运算符。
     *
     * @param string
     * @return
     */
    public static boolean matchOperationSymbol(String string) {
        if (string == null){
            return false;
        }
        Matcher matcher = operationSymbol.matcher(string);
        return matcher.matches();
    }

    public static void main(String[] args) {
        String formula = "ADD({self.array_1}, {self.subForm_1.num_22}, {self.num_1}, {dept.1}, {user.1}, {32323.text_1}, {43545.num_1})";
        String formula1 = "ADD({1.429.17072.num_1}, {1.429.17072.num_1}, {1.429.17072.num_1}, {dept.1}, {user.1}, {32323.text_1}, {43545.num_1})";
        String[] array1 = "1.429.17072.num_1".split("\\.");
        for (int i = 0; i < array1.length; i++) {
            System.out.println(array1[i]);
        }

    }

    public static Pattern getCheckFormulaField(){
        return checkFormulaField;
    }

    /**
     * 判断一个字符串是否是url。
     *
     * @param url
     * @return true 是 , false 否
     */
    public static boolean isUrl(String url) {
        if (url == null){
            return false;
        }
        Matcher matcher = urlPattern.matcher(url);
        return matcher.matches();
    }


}
